home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / frontends / sys2nf.c < prev   
C/C++ Source or Header  |  1993-01-29  |  7KB  |  333 lines

  1. /*  $Revision: 1.3 $
  2. **
  3. **  Read a C news "sys" file and split it up into a set of INN
  4. **  newsfeeds entries.  Also works with B news.
  5. **
  6. **  Once done, edit all files that have HELP or all in them.
  7. **  Review all files, anyway.
  8. */
  9. #include "configdata.h"
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include "nntp.h"
  16. #include "libinn.h"
  17. #include "clibrary.h"
  18. #include "macros.h"
  19.  
  20. #define TEMPFILE    ":tmp"
  21. static char        **Groups;
  22.  
  23.  
  24. /*
  25. **  Fill in the Groups array with the names of all active newsgroups.
  26. */
  27. static void
  28. ReadActive(act)
  29.     char    *act;
  30. {
  31.     FILE    *F;
  32.     int        i;
  33.     char    buff[BUFSIZ];
  34.     char    *p;
  35.  
  36.     /* Open file, count lines. */
  37.     if ((F = fopen(act, "r")) == NULL) {
  38.     perror(act);
  39.     exit(1);
  40.     }
  41.     for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++)
  42.     continue;
  43.     Groups = NEW(char*, i + 2);
  44.  
  45.     /* Fill in each word. */
  46.     rewind(F);
  47.     for (i = 0; fgets(buff, sizeof buff, F) != NULL; i++) {
  48.     if ((p = strchr(buff, ' ')) != NULL)
  49.         *p = '\0';
  50.     Groups[i] = COPY(buff);
  51.     }
  52.     Groups[i] = NULL;
  53.     (void)fclose(F);
  54. }
  55.  
  56.  
  57. /*
  58. **  Read in the sys file and turn it into an array of strings, one
  59. **  per continued line.
  60. */
  61. char **
  62. ReadSys(sys)
  63.     char        *sys;
  64. {
  65.     register char    *p;
  66.     register char    *to;
  67.     register char    *site;
  68.     register int    i;
  69.     char        *data;
  70.     char        **strings;
  71.  
  72.     /* Read in the file, get rough count. */
  73.     if ((data = ReadInFile(sys, (struct stat *)NULL)) == NULL) {
  74.     perror(sys);
  75.     exit(1);
  76.     }
  77.     for (p = data, i = 0; (p = strchr(p, '\n')) != NULL; p++, i++)
  78.     continue;
  79.  
  80.     /* Scan the file, glue all multi-line entries. */
  81.     for (strings = NEW(char*, i + 1), i = 0, to = p = data; *p; ) {
  82.     for (site = to; *p; ) {
  83.         if (*p == '\n') {
  84.         p++;
  85.         *to = '\0';
  86.         break;
  87.         }
  88.         if (*p == '\\' && p[1] == '\n')
  89.         while (*++p && CTYPE(isspace, *p))
  90.             continue;
  91.         else
  92.         *to++ = *p++;
  93.     }
  94.     *to++ = '\0';
  95.     if (*site == '\0')
  96.         continue;
  97.     strings[i++] = COPY(site);
  98.     }
  99.     strings[i] = NULL;
  100.     DISPOSE(data);
  101.     return strings;
  102. }
  103.  
  104.  
  105. /*
  106. **  Is this the name of a top-level group?  We want a simple name, "foo",
  107. **  and should find a "foo." in the group list.
  108. */
  109. static BOOL
  110. Toplevel(p)
  111.     char    *p;
  112. {
  113.     char    **gp;
  114.     char    *g;
  115.     int        i;
  116.  
  117.     if (strchr(p, '.') != NULL)
  118.     return FALSE;
  119.     for (i = strlen(p) - 1, gp = Groups; (g = *gp++) != NULL; )
  120.     if (EQn(p, g, i) && g[i + 1] == '.')
  121.         return TRUE;
  122.     return FALSE;
  123. }
  124.  
  125.  
  126. /*
  127. **  Do we have a name that's a prefix for more then one newsgroup?
  128. **  For "foo.bar", we must find more then one "foo.bar" or "foo.bar."
  129. */
  130. static BOOL
  131. GroupPrefix(p)
  132.     char    *p;
  133. {
  134.     char    **gp;
  135.     char    *g;
  136.     int        count;
  137.     int        i;
  138.  
  139.     if (strchr(p, '.') == NULL)
  140.     return FALSE;
  141.     for (i = strlen(p), count = 0, gp = Groups; (g = *gp++) != NULL; )
  142.     if (EQ(p, g) || (EQn(p, g, i) && g[i] == '.'))
  143.         count++;
  144.     return count > 1;
  145. }
  146.  
  147.  
  148. /*
  149. **  Step through the old subscription list, try to update each one in
  150. **  turn.
  151. */
  152. static void
  153. DoSub(F, p)
  154.     register FILE    *F;
  155.     char        *p;
  156. {
  157.     register char    *s;
  158.     register int    len;
  159.     register BOOL    SawBang;
  160.     register BOOL    SawAll;
  161.  
  162.     if ((s = strtok(p, ",")) == NULL)
  163.     return;
  164.  
  165.     (void)fprintf(F, "!*");
  166.     len = 8 + 1 + 2;
  167.     do {
  168.     /* These are distributions, not newsgroups. */
  169.     if (EQ(s, "world") || EQ(s, "na") || EQ(s, "usa") || EQ(s, "inet")
  170.      || EQ(s, "mod") || EQ(s, "net")
  171.      || EQ(s, "local")
  172.     )
  173.         continue;
  174.  
  175. #if    defined(DO_MERGE_TO_GROUPS)
  176.     if (EQ(s, "!to") || EQn(s, "to.", 3))
  177.         continue;
  178. #endif    /* defined(DO_MERGE_TO_GROUPS) */
  179.  
  180.     (void)putc(',', F);
  181.     len++;
  182.  
  183.     if (len + strlen(s) + 3 > 72) {
  184.         (void)fprintf(F,"\\\n\t    ");
  185.         len = 12;
  186.     }
  187.  
  188.     SawBang = *s == '!';
  189.     if (SawBang) {
  190.         (void)putc('!', F);
  191.         len++;
  192.         s++;
  193.     }
  194.  
  195.     SawAll = EQ(s, "all");
  196.     if (SawAll)
  197.         s = SawBang ? "*" : "*,!control";
  198.     len += strlen(s);
  199.     (void)fprintf(F, "%s", s);
  200.  
  201.     if (SawAll)
  202.         ;
  203.     else if (
  204.         EQ(s, "comp") || EQ(s, "misc") || EQ(s, "news") || EQ(s, "rec")
  205.      || EQ(s, "sci") || EQ(s, "soc") || EQ(s, "talk")
  206.  
  207.      || EQ(s, "alt") || EQ(s, "bionet") || EQ(s, "bit") || EQ(s, "biz")
  208.      || EQ(s, "clari") || EQ(s, "ddn") || EQ(s, "gnu") || EQ(s, "ieee")
  209.      || EQ(s, "k12") || EQ(s, "pubnet") || EQ(s, "trial") || EQ(s, "u3b")
  210.      || EQ(s, "vmsnet")
  211.  
  212.      || EQ(s, "ba") || EQ(s, "ca") || EQ(s, "dc") || EQ(s, "ne")
  213.      || EQ(s, "ny") || EQ(s, "tx")
  214.  
  215.      || EQ(s, "info") || EQ(s, "mail") || EQ(s, "opinions")
  216.      || EQ(s, "uunet")
  217.  
  218.      || Toplevel(s)) {
  219.         (void)fprintf(F, ".*");
  220.         len += 2;
  221.     }
  222.     else if (GroupPrefix(s)) {
  223.         (void)putc('*', F);
  224.         len++;
  225.     }
  226.     } while ((s = strtok((char *)NULL, ",")) != NULL);
  227. }
  228.  
  229.  
  230. int
  231. main(ac, av)
  232.     int         ac;
  233.     char    *av[];
  234. {
  235.     FILE    *F;
  236.     FILE    *out;
  237.     char    **sites;
  238.     char    *f2;
  239.     char    *f3;
  240.     char    *f4;
  241.     char    *p;
  242.     char    *q;
  243.     char    *site;
  244.     char    buff[256];
  245.     char    *act;
  246.     char    *dir;
  247.     char    *sys;
  248.     int        i;
  249.  
  250.     /* Set defaults. */
  251.     act = "/usr/local/lib/newslib/active";
  252.     sys = "sys";
  253.     dir = "feeds";
  254.     while ((i = getopt(ac, av, "a:s:d:")) != EOF)
  255.     switch (i) {
  256.     default:
  257.     exit(1);
  258.     /* NOTREACHED */
  259.     case 'a':    act = optarg;    break;
  260.     case 'd':    dir = optarg;    break;
  261.     case 's':    sys = optarg;    break;
  262.     }
  263.  
  264.     sites = ReadSys(sys);
  265.     ReadActive(act);
  266.     if (mkdir(dir, 0777) < 0 && errno != EEXIST)
  267.     perror(dir), exit(1);
  268.     if (chdir(dir) < 0)
  269.     perror("chdir"), exit(1);
  270.     for ( ; ; ) {
  271.     /* Get next non-comment ilne. */
  272.     if ((p = *sites++) == NULL)
  273.         break;
  274.     for (F = fopen(TEMPFILE, "w"); p && *p == '#'; p = *sites++)
  275.         (void)fprintf(F, "%s\n", p);
  276.     if (p == NULL) {
  277.         (void)fclose(F);
  278.         break;
  279.     }
  280.     site = COPY(p);
  281.     if ((f2 = strchr(site, ':')) == NULL)
  282.         f2 = "HELP";
  283.     else
  284.         *f2++ = '\0';
  285.     if ((f3 = strchr(f2, ':')) == NULL)
  286.         f3 = "HELP";
  287.     else
  288.         *f3++ = '\0';
  289.     if ((f4 = strchr(f3, ':')) == NULL)
  290.         f4 = "HELP";
  291.     else
  292.         *f4++ = '\0';
  293.  
  294.     /* Write the fields. */
  295.     (void)fprintf(F, "%s\\\n", site);
  296.     (void)fprintf(F, "\t:");
  297.     DoSub(F, f2);
  298.     (void)fprintf(F, "\\\n");
  299.     if (EQ(f3, "n"))
  300.         (void)fprintf(F, "\t:Tf,Wnm\\\n", f3);
  301.     else
  302.         (void)fprintf(F, "\t:HELP%s\\\n", f3);
  303.     (void)fprintf(F, "\t:%s\n", f4);
  304.     if (ferror(F) || fclose(F) == EOF)
  305.         perror(TEMPFILE), exit(1);
  306.  
  307.     DISPOSE(site);
  308.  
  309.     /* Find the sitename. */
  310.     for (q = p; *q && *q != '/' && *q != ':'; q++)
  311.         continue;
  312.     *q = '\0';
  313.  
  314.     /* Append temp file to site file. */
  315.     if ((F = fopen(TEMPFILE, "r")) == NULL)
  316.         perror(TEMPFILE), exit(1);
  317.     if ((out = xfopena(p)) == NULL)
  318.         perror(p), exit(1);
  319.     while ((i = fread(buff, 1, sizeof buff, F)) > 0)
  320.         if (fwrite(buff, 1, i, out) != i)
  321.         perror(p), exit(1);
  322.     (void)fclose(F);
  323.     if (fclose(out) == EOF)
  324.         perror(p), exit(1);
  325.  
  326.     if (unlink(TEMPFILE) < 0)
  327.         perror("can't unlink temp file");
  328.     }
  329.  
  330.     exit(0);
  331.     /* NOTREACHED */
  332. }
  333.